# -*- coding: utf-8 -*-
from tool.gongju import *
from tool.zhibiao import ema_z


def 固定点位出场_v1(cl):
    """
    固定价位出场，设置价格，价格到后平仓，需手动调整仓位
    """
    # 数据初始化，
    Datetime = cl.klines[0].datetime.values
    # Close = cl.klines[0].close.values
    High = cl.klines[0].high.values
    Low = cl.klines[0].low.values
    # Open = cl.klines[0].open.values
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    # shijian = int(time_to_datetime(Datetime[-1]).time().strftime("%H%M%S"))  # k线当前时间

    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    yxfs = cl.jiaoyishezhi[5][1]  # 0表示止盈，1表示止损
    zyzsjg = cl.jiaoyishezhi[5][2]  # 止盈或止损价格

    # 交易逻辑执行区
    if yxfs == 1:  # 为启动止损
        if chicang > 0 and Low[-1] < zyzsjg:  # 平多
            Sell(ss, Low[-1], canshu)
        else:
            if chicang < 0 and High[-1] > zyzsjg:  # 平空
                BuyToCover(ss, High[-1], canshu)
    else:
        if yxfs == 0:  # 为启动止盈
            if chicang > 0 and High[-1] < zyzsjg:  # 平多
                Sell(ss, High[-1], canshu)
            else:
                if chicang < 0 and Low[-1] < zyzsjg:  # 平空
                    BuyToCover(ss, Low[-1], canshu)

    return '固定', '止盈', '止损', '出场'


def 根据仓位吊灯出场_v1(cl):
    """
    合约本身价格吊灯出场
    """
    # 数据初始化，
    # Close = cl.klines[0].close.values
    Open = cl.klines[0].open.values
    Datetime = cl.klines[0].datetime.values
    # riqishijian = time_to_datetime(Datetime[-1])
    # shijian = int(riqishijian.time().strftime("%H%M%S"))  # 当前时间,格式为161500
    # riqi = riqishijian.date().strftime("%Y%m%d")  # 当前日期，格式为20210828
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    chicangshuliang = cl.openingdata['kaicangshuliang'] * chicang
    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    ccts = cl.jiaoyishezhi[5][1]  # 出场跳数
    zhbh = cl.jiaoyishezhi[0][0]  # 开仓账户编号
    heyue = cl.jiaoyishezhi[3][0]

    # 全局变量的初始化，为空的时候执行
    if 'zxbd' not in cl.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl.sjb['zxbd'] = cl.zhanghu[zhbh].get_zuixiaobiandong(cl.jiaoyishezhi[3][0])   # 最小变动单位
        cl.sjb['ccts'] = cl.sjb['zxbd'] * ccts
        cl.sjb['zdts'] = 1 * ccts
        cl.sjb['cczt'] = 0  # 上一次开仓的状态
        cl.sjb['ks'] = 0  # 开仓后止损亏损了多少跳
        cl.sjb['zdz'] = 0  # 平仓后向不利方向运行值
        cl.sjb['xdid'] = '888888'  # 下单id

    # # 指标计算区
    # if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
    #     pass

    zuixinjia = DuquRedis_HQ(heyue)['LastPrice'] # 最新价

    if 'kcj' not in cl.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl.sjb['kcj'] = zuixinjia  # 开仓价
        cl.sjb['pcj'] = zuixinjia  # 平仓的价格

    ccss = cl.zhanghu[zhbh].get_chicang(heyue)[0]

    # 账户持仓放入显示
    if ccss != chicangshuliang:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)
        cl.sjb['kcj'] = zuixinjia
        cl.sjb['cczt'] = 0

    if cl.sjb['cczt'] == 0 and cl.jiaoyiqidong:
        if ccss > 0:
            cl.sjb['kcj'] = max(cl.sjb['kcj'], zuixinjia)
            cl.sjb['ks'] = round(cl.sjb['kcj'] - zuixinjia, 2)
            if cl.sjb['ks'] > cl.sjb['ccts']:
                cl.sjb['cczt'] = 1
                cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, 1, ccss)  # 平多
                cl.sjb['pcj'] = zuixinjia
            else:  # 条件又不满足后撤单
                if cl.sjb['ks'] < cl.sjb['ccts']:
                    if cl.sjb['xdid'] in cl.zhanghu[zhbh].order_dict:
                        if cl.zhanghu[zhbh].order_dict[cl.sjb['xdid']]['kcdsl'] != 0:
                            cl.zhanghu[zhbh].cd_orders(cl.sjb['xdid'])  # 撤挂单
                            cl.sjb['cczt'] = 0
        else:
            if ccss < 0:
                cl.sjb['kcj'] = min(cl.sjb['kcj'], zuixinjia)
                cl.sjb['ks'] = round(zuixinjia-cl.sjb['kcj'], 2)
                if cl.sjb['ks'] > cl.sjb['ccts']:
                    cl.sjb['cczt'] = -1
                    cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, -1, abs(ccss))  # 平空
                    cl.sjb['pcj'] = zuixinjia
                else:  # 条件又不满足后撤单
                    if cl.sjb['ks'] > cl.sjb['ccts']:
                        if cl.sjb['xdid'] in cl.zhanghu[zhbh].order_dict:
                            if cl.zhanghu[zhbh].order_dict[cl.sjb['xdid']]['kcdsl'] != 0:
                                cl.zhanghu[zhbh].cd_orders(cl.sjb['xdid'])  # 撤挂单
                                cl.sjb['cczt'] = 0

        # 追单系统
        if cl.sjb['cczt'] != 0:
            if cl.sjb['xdid'] in cl.zhanghu[zhbh].order_dict:
                if cl.zhanghu[zhbh].order_dict[cl.sjb['xdid']]['kcdsl'] != 0:
                    if cl.sjb['cczt'] == 1:  # 为开的平多单
                        cl.sjb['zdz'] = round(cl.sjb['pcj'] - zuixinjia, 2)
                        if cl.sjb['zdz'] > cl.sjb['zdts']:
                            cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, 1, ccss)  # 追单平多
                            cl.sjb['pcj'] = zuixinjia
                    else:
                        if cl.sjb['cczt'] == -1:  # 为开的平空单
                            # cl.sjb['zdz'] = round(zuixinjia - cl.sjb['pcj'], 2)
                            cl.sjb['zdz'] = round(zuixinjia - cl.sjb['pcj'], 2)
                            if cl.sjb['zdz'] > cl.sjb['zdts']:
                                cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, -1, ccss)  # 追单平空
                                cl.sjb['pcj'] = zuixinjia

    return zuixinjia, cl.sjb['kcj'], cl.sjb['ks'], cl.sjb['cczt']


def 由tick计算指数_v1(ls):
    """
    从数据库中读取合约后，合成约指数最新价，用于合成指数合约k线，采用持仓量加权
    :param ls: 本合约有持仓持仓量的所有合约列表，
    :return: 指数化后的最新价，成交量和，持仓量和
    """
    chicanglianghe = 0  # 持仓量之和
    chengjiaolianghe = 0  # 成交量之和
    jcsj = []  # 临时变量用于储存每个合约的最新价
    ccl = []  # 临时变量用于存放每个合约的持仓量
    for ss in ls:  # 循环所有合约
        try:
            lsbl = DuquRedis_HQ(ss)  # 获取当前合约的tick数据
            chicanglianghe += lsbl['OpenInterest']  # 所有合约持仓量之和
            chengjiaolianghe += lsbl['Volume']  # 所有合约成交量之和
            jcsj.append(lsbl['LastPrice'])  # 保存当前合约最新价
            ccl.append(lsbl['OpenInterest'])  # 保存当前合约持仓量
        except:
            # print(ss, '没有此合约数据，请订阅')
            pass
    # shijian = DuquRedis_hangqing(ls[0])['UpdateTime']  # 获取主力合约时间
    # 指数算法公式：sum（每个品种价格*持仓量/所有合约总持仓量）
    zuixinjia = round((np.array(jcsj)*np.array(ccl)/chicanglianghe).sum(), 1)  # 计算指数最新价

    return chicanglianghe, chengjiaolianghe, zuixinjia


def 根据仓位指数价格吊灯出场_v2(cl):
    """
    计算指定合约的指数，根据指数合约价格移动平仓，指数吊灯出场
    """
    # 数据初始化，
    Open = cl.klines[0].open.values
    Datetime = cl.klines[0].datetime.values
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    chicangshuliang = cl.openingdata['kaicangshuliang'] * chicang
    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    ccts = cl.jiaoyishezhi[5][1]  # 出场跳数
    zhbh = cl.jiaoyishezhi[0][0]  # 开仓账户编号
    heyue = cl.jiaoyishezhi[3][0]

    # 全局变量的初始化，为空的时候执行
    if 'zxbd' not in cl.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl.sjb['zxbd'] = cl.zhanghu[zhbh].get_zuixiaobiandong(cl.jiaoyishezhi[3][0])   # 最小变动单位
        cl.sjb['ccts'] = cl.sjb['zxbd'] * ccts
        cl.sjb['zdts'] = 1 * ccts
        cl.sjb['cczt'] = 0  # 上一次开仓的状态
        cl.sjb['ks'] = 0  # 开仓后止损亏损了多少跳
        cl.sjb['zdz'] = 0  # 平仓后向不利方向运行值
        cl.sjb['xdid'] = '888888'  # 下单id
        cl.sjb["所有合约"] = cl.zhanghu[zhbh].get_pinzhong_zaijiaoyiheyue(GetProduct(heyue))

    # # 指标计算区
    # if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
    #     pass

    # 指数合成计算
    penInterest, Volume, zuixinjia = 由tick计算指数_v1(cl.sjb["所有合约"])
    # print(penInterest, Volume, zuixinjia)
    zuixinjia = round(round(zuixinjia / cl.sjb['zxbd']) * cl.sjb['zxbd'], 1)  # 将小数为转换为和最小变动单位一致

    if 'kcj' not in cl.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl.sjb['kcj'] = zuixinjia  # 开仓价
        cl.sjb['pcj'] = zuixinjia  # 平仓的价格
    # 账户仓位数据获取
    ccss = cl.zhanghu[zhbh].get_chicang(heyue)[0]
    # 账户持仓放入显示
    if ccss != chicangshuliang:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)
        cl.sjb['kcj'] = zuixinjia
        cl.sjb['cczt'] = 0

    if cl.sjb['cczt'] == 0 and cl.jiaoyiqidong:
        if ccss > 0:
            cl.sjb['kcj'] = max(cl.sjb['kcj'], zuixinjia)
            cl.sjb['ks'] = round(cl.sjb['kcj'] - zuixinjia, 2)
            if cl.sjb['ks'] > cl.sjb['ccts']:
                cl.sjb['cczt'] = 1
                cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, 1, ccss)  # 平多
                cl.sjb['pcj'] = zuixinjia
            else:  # 条件又不满足后撤单
                if cl.sjb['ks'] < cl.sjb['ccts']:
                    if cl.sjb['xdid'] in cl.zhanghu[zhbh].order_dict:
                        if cl.zhanghu[zhbh].order_dict[cl.sjb['xdid']]['kcdsl'] != 0:
                            cl.zhanghu[zhbh].cd_orders(cl.sjb['xdid'])  # 撤挂单
                            cl.sjb['cczt'] = 0
        else:
            if ccss < 0:
                cl.sjb['kcj'] = min(cl.sjb['kcj'], zuixinjia)
                cl.sjb['ks'] = round(zuixinjia-cl.sjb['kcj'], 2)
                if cl.sjb['ks'] > cl.sjb['ccts']:
                    cl.sjb['cczt'] = -1
                    cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, -1, abs(ccss))  # 平空
                    cl.sjb['pcj'] = zuixinjia
                else:  # 条件又不满足后撤单
                    if cl.sjb['ks'] > cl.sjb['ccts']:
                        if cl.sjb['xdid'] in cl.zhanghu[zhbh].order_dict:
                            if cl.zhanghu[zhbh].order_dict[cl.sjb['xdid']]['kcdsl'] != 0:
                                cl.zhanghu[zhbh].cd_orders(cl.sjb['xdid'])  # 撤挂单
                                cl.sjb['cczt'] = 0

        # 追单系统
        if cl.sjb['cczt'] != 0:
            if cl.sjb['xdid'] in cl.zhanghu[zhbh].order_dict:
                if cl.zhanghu[zhbh].order_dict[cl.sjb['xdid']]['kcdsl'] != 0:
                    if cl.sjb['cczt'] == 1:  # 为开的平多单
                        cl.sjb['zdz'] = round(cl.sjb['pcj'] - zuixinjia, 2)
                        if cl.sjb['zdz'] > cl.sjb['zdts']:
                            cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, 1, ccss)  # 追单平多
                            cl.sjb['pcj'] = zuixinjia
                    else:
                        if cl.sjb['cczt'] == -1:  # 为开的平空单
                            # cl.sjb['zdz'] = round(zuixinjia - cl.sjb['pcj'], 2)
                            cl.sjb['zdz'] = round(zuixinjia - cl.sjb['pcj'], 2)
                            if cl.sjb['zdz'] > cl.sjb['zdts']:
                                cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, -1, ccss)  # 追单平空
                                cl.sjb['pcj'] = zuixinjia

    return zuixinjia, cl.sjb['kcj'], cl.sjb['ks'], cl.sjb['cczt']


def diaodengchuchang_v4(cl):
    """
    总体思路:对已持仓品种执行一条或者多条命令（因为持仓有可能多品种）。开仓后，若价格反方向运行，则以开仓后最优价为准，方向运行至一定点数后（具体点数需手动输入），
    执行平仓或锁仓。
    1，若开多仓，最优价就是开仓后的最高价，若价格运行低于该最高价一定点数（手动输入具体点数）后，根据盘面价格情况，第一时间以最优价执行平仓或锁仓（手动输入）。
    2，若开空仓，最优价就是开仓后的最低价，若价格运行高于该最低价一定点数（手动输入具体点数）后，根据盘面价格情况，第一时间以最优价执行平仓或锁仓（手动输入）。
    """
    # 数据初始化，
    # Close = cl.klines[0].close.values
    Open = cl.klines[0].open.values
    Datetime = cl.klines[0].datetime.values
    # riqishijian = time_to_datetime(Datetime[-1])
    # shijian = int(riqishijian.time().strftime("%H%M%S"))  # 当前时间,格式为161500
    # riqi = riqishijian.date().strftime("%Y%m%d")  # 当前日期，格式为20210828
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    chicangshuliang = cl.openingdata['kaicangshuliang'] * chicang
    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    止损点数 = cl.jiaoyishezhi[5][1]
    启动止盈点数 = cl.jiaoyishezhi[5][2]
    盈利回落点数 = cl.jiaoyishezhi[5][3]

    zhbh = cl.jiaoyishezhi[0][0]  # 开仓账户编号
    heyue = cl.jiaoyishezhi[3][0]
    zuixinjia = DuquRedis_HQ(heyue)['LastPrice'] # 最新价
    # 全局变量的初始化，为空的时候执行
    if 'zxbd' not in cl.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl.sjb['zxbd'] = cl.zhanghu[zhbh].get_zuixiaobiandong(cl.jiaoyishezhi[3][0])   # 最小变动单位
        cl.sjb['cczt'] = 0  # 上一次开仓的状态
        cl.sjb['亏损'] = 0  # 开仓后止损亏损了多少跳
        cl.sjb['开仓后最高价'] = 0
        cl.sjb['盈利回吐'] = 0
        cl.sjb['最高盈利'] = 0
        cl.sjb['xdid'] = '888888'  # 下单id
        cl.sjb['开仓价'] = zuixinjia
        cl.sjb['平仓价'] = zuixinjia
        cl.sjb['平仓时间'] = time.time()
        # 用于在软件右键策略字典中查看参数输入说明，和指标输出含义说明
        cl.sjb['参数说明'] = {"1":'策略开关', '2':'止损点数', '3':'启动止盈点数', '4':'利润回落多少平仓'}
        cl.sjb['输出指标说明'] = {"指标1": '最新价', '指标2': '开仓价', '指标3': '亏损多少点', '指标4': '最高盈利多少点'}
    # # 指标计算区
    # if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
    #     pass

    # 账户持仓获取
    ccss = chazhaoheyue_duiyingchicang(cl.zhanghu[zhbh].df_cc, heyue)  # 获取该合约持仓
    if len(ccss) == 2:
        ccss = ccss[0]+ccss[1]  # 求出净持仓
    else:
        ccss = ccss[0]

    # 账户持仓放入显示
    if ccss != chicangshuliang and time.time()-cl.sjb['平仓时间']>2:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)
        cl.sjb['开仓价'] = zuixinjia
        cl.sjb['开仓后最高价'] = zuixinjia
        cl.sjb['cczt'] = 0

    if cl.sjb['cczt'] == 0 and cl.jiaoyiqidong:
        if ccss > 0 and cl.sjb['cczt'] == 0:
            cl.sjb['开仓后最高价'] = max(cl.sjb['开仓后最高价'], zuixinjia)
            cl.sjb['盈利回吐'] = round(cl.sjb['开仓后最高价'] - zuixinjia, 2)
            cl.sjb['最高盈利'] = round(cl.sjb['开仓后最高价'] - cl.sjb['开仓价'], 2)
            cl.sjb['亏损'] = round(cl.sjb['开仓价'] - zuixinjia, 2)
            if cl.sjb['亏损'] > 止损点数:  # 止损平仓
                cl.sjb['cczt'] = 1
                cl.sjb['平仓时间'] = time.time()
                cl.sjb['xdid'] = Sell(ccss, zuixinjia, canshu)  # 平多
                cl.sjb['平仓价'] = zuixinjia

            if cl.sjb['最高盈利'] > 启动止盈点数 and cl.sjb['盈利回吐'] > 盈利回落点数:
                cl.sjb['cczt'] = 1
                cl.sjb['平仓时间'] = time.time()
                cl.sjb['xdid'] = Sell(ccss, zuixinjia, canshu)  # 平多
                cl.sjb['平仓价'] = zuixinjia

        else:
            if ccss < 0 and cl.sjb['cczt'] == 0:
                cl.sjb['开仓后最高价'] = min(cl.sjb['开仓后最高价'], zuixinjia)
                cl.sjb['盈利回吐'] = round(zuixinjia-cl.sjb['开仓后最高价'], 2)
                cl.sjb['最高盈利'] = round(cl.sjb['开仓价'] - cl.sjb['开仓后最高价'], 2)
                cl.sjb['亏损'] = round(zuixinjia-cl.sjb['开仓价'], 2)
                if cl.sjb['亏损'] > 止损点数:  # 止损平仓
                    cl.sjb['cczt'] = -1
                    cl.sjb['平仓时间'] = time.time()
                    cl.sjb['xdid'] = BuyToCover(abs(ccss), zuixinjia, canshu)  # 平空
                    cl.sjb['平仓价'] = zuixinjia

                if cl.sjb['最高盈利'] > 启动止盈点数 and cl.sjb['盈利回吐'] > 盈利回落点数:
                    cl.sjb['cczt'] = -1
                    cl.sjb['平仓时间'] = time.time()
                    cl.sjb['xdid'] = BuyToCover(abs(ccss), zuixinjia, canshu)  # 平空
                    cl.sjb['平仓价'] = zuixinjia

    return zuixinjia, cl.sjb['开仓价'], cl.sjb['亏损'], cl.sjb['最高盈利']


def ema均线出场_v1(cl):
    """
    ema均线出场，需手动手输入仓位
    """
    # 数据初始化，
    Datetime = cl.klines[0].datetime.values
    Close = cl.klines[0].close.values
    # High = cl.klines[0].high.values
    # Low = cl.klines[0].low.values
    Open = cl.klines[0].open.values
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    # shijian = int(time_to_datetime(Datetime[-1]).time().strftime("%H%M%S"))  # k线当前时间

    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    mazq = cl.jiaoyishezhi[5][1]  # ma周期
    sfqd = cl.jiaoyishezhi[5][2]  # 是否启动平仓，0为停止，大于0为启动
    # 指标计算区
    ema = ema_z(Close, mazq)
    ema = round(ema[-2], 2)
    # 交易逻辑执行区
    if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
        if sfqd > 0:
            if chicang > 0 and Close[-2] < ema:  # 平多
                Sell(ss, Open[-2], canshu)
            else:
                if chicang < 0 and Close[-2] > ema:  # 平空
                    BuyToCover(ss, Open[-2], canshu)

    shifouqidong = '启动' if sfqd > 0 else '停止'
    return ema, 'ema', '出场', shifouqidong


def 根据仓位ema均线出场_v2(cl):
    """
    ema均线出场,有仓位就自动运行
    """
    # 数据初始化，
    Close = cl.klines[0].close.values
    Open = cl.klines[0].open.values
    Datetime = cl.klines[0].datetime.values
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    chicangshuliang = cl.openingdata['kaicangshuliang'] * chicang
    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    mazq = cl.jiaoyishezhi[5][1]  # ma周期
    sfqd = cl.jiaoyishezhi[5][2]  # 是否启动平仓，0为停止，大于0为启动
    zhbh = cl.jiaoyishezhi[0][0]
    heyue = cl.jiaoyishezhi[3][0]

    ccss = cl.zhanghu[zhbh].get_chicang(heyue)[0]  # 持仓获取

    # 账户持仓放入显示
    if ccss != chicangshuliang:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)

    # 指标计算区
    ema = ema_z(Close, mazq)
    ema = round(ema[-2], 2)
    # 交易逻辑执行区
    if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
        if sfqd > 0:
            if chicang > 0 and Close[-2] < ema:  # 平多
                Sell(ss, Open[-2], canshu)
            else:
                if chicang < 0 and Close[-2] > ema:  # 平空
                    BuyToCover(ss, Open[-2], canshu)

    shifouqidong = '启动' if sfqd > 0 else '停止'

    return ema, 'ema', '出场', shifouqidong


def macd的diff出场_v1(cl):
    """
    macd的diff出场，需手动设置仓位
    """
    # 数据初始化，
    Datetime = cl.klines[0].datetime.values
    Close = cl.klines[0].close.values
    # High = cl.klines[0].high.values
    # Low = cl.klines[0].low.values
    Open = cl.klines[0].open.values
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']

    # shijian = int(time_to_datetime(Datetime[-1]).time().strftime("%H%M%S"))  # k线当前时间

    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    mazq = cl.jiaoyishezhi[5][1]  # ma周期
    sfqd = cl.jiaoyishezhi[5][2]  # 是否启动平仓，0为停止，大于0为启动
    # 指标计算区
    diff = ema_z(Close, 12) - ema_z(Close, 26)
    diff = round(diff[-2], 4)
    # 交易逻辑执行区
    if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
        if sfqd > 0:
            if chicang > 0 and diff < 0:  # 平多
                Sell(ss, Open[-2], canshu)
            else:
                if chicang < 0 and diff > 0:  # 平空
                    BuyToCover(ss, Open[-2], canshu)

    shifouqidong = '启动' if sfqd > 0 else '停止'
    return diff, 'diff', '出场', shifouqidong


def 根据仓位macd的diff出场_v2(cl):
    """
    macd的diff出场，,有仓位就自动运行
    """
    # 数据初始化，
    Datetime = cl.klines[0].datetime.values
    Close = cl.klines[0].close.values
    # High = cl.klines[0].high.values
    # Low = cl.klines[0].low.values
    Open = cl.klines[0].open.values
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    chicangshuliang = cl.openingdata['kaicangshuliang'] * chicang
    # shijian = int(time_to_datetime(Datetime[-1]).time().strftime("%H%M%S"))  # k线当前时间

    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    mazq = cl.jiaoyishezhi[5][1]  # ma周期
    sfqd = cl.jiaoyishezhi[5][2]  # 是否启动平仓，0为停止，大于0为启动
    zhbh = cl.jiaoyishezhi[0][0]

    # 指标计算区
    diff = ema_z(Close, 12) - ema_z(Close, 26)
    diff = round(diff[-2], 4)

    ccss = cl.zhanghu[zhbh].get_chicang(heyue)[0]

    # 账户持仓放入显示
    if ccss != chicangshuliang:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)

    # 交易逻辑执行区
    if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
        if sfqd > 0:
            if chicang > 0 and diff < 0:  # 平多
                Sell(ss, Open[-2], canshu)
            else:
                if chicang < 0 and diff > 0:  # 平空
                    BuyToCover(ss, Open[-2], canshu)

    shifouqidong = '启动' if sfqd > 0 else '停止'
    return diff, 'diff', '出场', shifouqidong


def 根据仓位固定百分比_止盈1(cl):
    """
    固定百分比止盈，根据已有仓位自动运行
    """
    # 数据初始化，
    # Close = cl.klines[0].close.values
    Open = cl.klines[0].open.values
    Datetime = cl.klines[0].datetime.values
    # riqishijian = time_to_datetime(Datetime[-1])
    # shijian = int(riqishijian.time().strftime("%H%M%S"))  # 当前时间,格式为161500
    # riqi = riqishijian.date().strftime("%Y%m%d")  # 当前日期，格式为20210828
    canshu = [cl.jiaoyiqidong, cl.zhanghu, cl.jiaoyishezhi, cl.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl.openingdata['kaicangzhuangtai']
    chicangshuliang = cl.openingdata['kaicangshuliang'] * chicang
    # 参数设置区
    ss = cl.jiaoyishezhi[5][0]  # 开仓数量
    ccts = cl.jiaoyishezhi[5][1]  # 出场百分比
    zhbh = cl.jiaoyishezhi[0][0]  # 开仓账户编号
    heyue = cl.jiaoyishezhi[3][0]

    # 全局变量的初始化，为空的时候执行
    if 'cczt' not in cl.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl.sjb['cczt'] = 0  # 上一次开仓的状态
        cl.sjb['kcj'] = zuixinjia  # 开仓价
        cl.sjb['pcj'] = zuixinjia  # 平仓的价格
        cl.sjb['盈利百分比'] = 0
        cl.sjb['xdid'] = '888888'  # 下单id

    # # 指标计算区
    # if cl.shangcishijian != Datetime[-1]:  # 更新k线时执行，一般用与计算指标
    #     pass

    DuquRedis_HQ(heyue)['LastPrice']  # 最新价
    # 账户仓位数据获取
    ccss = cl.zhanghu[zhbh].get_chicang(heyue)[0]

    # 账户持仓放入显示
    if ccss != chicangshuliang:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)
        cl.sjb['kcj'] = zuixinjia
        cl.sjb['cczt'] = 0

    if cl.sjb['cczt'] == 0 and cl.jiaoyiqidong:
        if ccss > 0:
            cl.sjb['盈利百分比'] = (zuixinjia-cl.sjb['kcj'])/cl.sjb['kcj']*100
            if ccts > cl.sjb['盈利百分比']:
                cl.sjb['cczt'] = 1
                cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, 1, ccss)  # 平多
        else:
            if ccss < 0:
                cl.sjb['盈利百分比'] = (cl.sjb['kcj']-zuixinjia) / cl.sjb['kcj'] * 100
                if cl.sjb['ks'] > cl.sjb['ccts']:
                    cl.sjb['cczt'] = -1
                    cl.sjb['xdid'] = cl.zhanghu[zhbh].pc_orders(cl.jiaoyishezhi, -1, abs(ccss))  # 平空


    return zuixinjia, cl.sjb['kcj'], cl.sjb['盈利百分比'], cl.sjb['cczt']
